package com.qire.manhua.dal.service;

import com.qire.antsbinder.dal.DataService;
import com.qire.antsbinder.dal.annotation.StrategyAnnotation;
import com.qire.antsbinder.dal.annotation.StrategyAnnotation.ThreadMode;
import com.qire.common.basic.ObjectUtil;
import com.qire.common.collect.ArrayUtil;
import com.qire.common.constant.TeensModeManage;
import com.qire.common.constant.Url;
import com.qire.common.dal.WarehouseFactory;
import com.qire.common.basic.StringUtil;
import com.qire.common.function.Action;
import com.qire.common.utils.ToastHelper;
import com.qire.common.widget.snackbar.Prompt;
import com.qire.manhua.dal.IComicDataDAL;
import com.qire.manhua.dal.ICommentDataDAL;
import com.qire.manhua.dal.ITradingDataDAL;
import com.qire.manhua.dal.IUserDataDAL;
import com.qire.manhua.model.entity.BulletScreenInfo;
import com.qire.manhua.model.entity.ComicBookEntity;
import com.qire.manhua.model.entity.ComicBookEntity.ChaptersInfo;
import com.qire.manhua.model.entity.ComicBookEntity.DirectoryInfo;
import com.qire.manhua.model.viewModel.impl.ComicReaderViewModel;
import com.qire.manhua.model.viewModel.impl.ComicReaderViewModel.ComicReaderItemViewModel;
import com.qire.manhua.model.vo.ChaptersBulletScreenVO;
import com.qire.manhua.model.vo.ChaptersResultsVO;
import com.qire.manhua.model.vo.CollectTaskVO;
import com.qire.manhua.model.vo.DirectoryVO;
import com.qire.manhua.model.vo.MyAccountVO;
import com.qire.manhua.model.vo.NewcomerWelfareCheckVO;
import com.qire.manhua.model.vo.OkResponseVO;
import com.qire.manhua.model.vo.TaskStateResponseVO;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * 漫画阅读页数据服务
 */
public class ComicReaderService extends DataService {

    private final IComicDataDAL comicDataDAL = WarehouseFactory.create(this, IComicDataDAL.class);

    private final ICommentDataDAL commentDataDAL = WarehouseFactory.create(this, ICommentDataDAL.class);

    private final ITradingDataDAL tradingDataDAL = WarehouseFactory.create(this, ITradingDataDAL.class);

    private final IUserDataDAL userDataDAL = WarehouseFactory.create(this, IUserDataDAL.class);

    private final DelayTaskPool delayTaskPool = new DelayTaskPool();

    private final ComicReaderViewModel viewModel;

    public ComicReaderService(ComicReaderViewModel viewModel) {
        this.viewModel = viewModel;
    }

    /**
     * 更新服务器阅读历史记录，之上报，不做响应故不写回调关注
     * @param readChapterId 阅读章节ID
     */
    public void updateReadHistory(int readChapterId) {
        comicDataDAL.updateReadHistory(viewModel.comicBookEntity().id, readChapterId);
    }

    /**
     * 加载漫画目录
     */
    public void loadComicDirectory() {
        comicDataDAL.fetchComicDirectoryInfo(viewModel.comicBookEntity().id);
    }
    @StrategyAnnotation(event = Url.comicDirectoryInfo)
    public void fetchDirectoryInfoApiCallbackRefresh(DirectoryVO data, boolean isCache) {

        if(data == null) {
            return;
        }

        if(!TeensModeManage.checkVisibleIfNeed(data.isTeensVisible())) {
            viewModel.teensRestrictReadTips();
            return;
        }

        ComicBookEntity comicBookEntity = viewModel.comicBookEntity();

        // 更新填充漫画实体对象数据
        data.updateComicBook(comicBookEntity);

        // 1.判定漫画实体是否存在解锁信息，如果不存在，则说明进入阅读页时没有提示过解锁，需要开启首次解锁提示浮层
        if(comicBookEntity.lockInfo() != null) {
            comicBookEntity.lockInfo().enableFirstUnlock();
        }

        // 2.更具目录预读章节
        for(DirectoryInfo directoryInfo : comicBookEntity.directoryInfoList) {
            viewModel.addComicReaderItem(directoryInfo.chaptersInfo);
        }

        viewModel.refreshComicReaderView();

        int position = viewModel.comicBookEntity().currentReadingChaptersPosition();
        viewModel.proxy().gotoChaptersPosition(position);


//        if(data.lockInfo != null) {
//            //NOTE: 1.判定漫画实体是否存在解锁信息，如果不存在，则说明进入阅读页时没有提示过解锁，需要开启首次解锁提示浮层
////            ComicBookEntity.LockInfo lockInfo = data.lockInfo.toLockInfo(comicBookEntity);
//            //todo: 新需求，不管提示与否都需要第一次显示解锁，固注释掉下面判断
////            if(comicBookEntity.lockInfo()==null)
//            lockInfo.enableFirstUnlock();
//            comicBookEntity.loadLockInfo(lockInfo);.
//        }
//
//        // 目录信息初始化
//        ArrayList<ComicReaderListItemModel> itemModelList = new ArrayList<>();
//        comicBookEntity.clearDirectoryList();
//        HashMap<Integer,DBDownloadChapter> downMap = DBManager.getInstance().queryDownloadChaptersToMap(comicBookEntity.id);
//        for(int index=0;index < data.chapters.size();index++) {
//            boolean isFinish = index >= data.chapters.size() - 1;
//
//            DirectoryVO.DirectoryItemVO directoryVO = data.chapters.get(index);
//
//            if(!NetworkUtils.isConnected(activity)){
//                DBDownloadChapter dbDownloadChapter = downMap.get(directoryVO.chapterId);
//                if(dbDownloadChapter == null || dbDownloadChapter.getStatus() != 3){
//                    continue;
//                }
//            }
//
//            ChaptersInfo  chaptersInfo  = comicBookEntity.chaptersPreInstalled(directoryVO.chapterId);
//            DirectoryInfo directoryInfo = directoryVO.toDirectoryInfo(comicBookEntity);
//            comicBookEntity.addDirectoryInfo(directoryInfo);
//            comicBookEntity.buildIndexing(directoryInfo,chaptersInfo);
//
//            //TODO:由于缓存的原因，可能导致该方法被缓存调用一次在请求网络返回，造成多线程下章节加载完毕后替换目录数据适配其中的VIEWMODEL没有加载到章节数据
//            //本初解决方案:1.使用增量更新，对比接口数据和缓存已加载到适配其中数据是否相同，只构造不同的数据；
//            //           2.使用唯一对象，如果存在数据直接使用原数据不存在则重新构造，此处简单处理,有待改进;
//            ComicReaderListItemModel itemModel = viewModel.pickComicReaderListItemModel(directoryVO.chapterId);
//            if(itemModel == null )
//                itemModel = new ComicReaderListItemModel(chaptersInfo, isFinish);
//
//            if(directoryInfo.haveLock()) {
//                ChaptersUnlockDialogViewModel chaptersUnlockDialogViewModel = new ChaptersUnlockDialogViewModel(activity);
//
//                chaptersUnlockDialogViewModel.loadComicData(comicBookEntity,directoryInfo);
//
//                itemModel.loadChaptersUnlockDialogViewModel(chaptersUnlockDialogViewModel);
//            }
//
//            itemModelList.add(itemModel);
//        }

//        viewModel.loadDataList(itemModelList);
//        viewModel.heartBtnRefresh();

//        int position = viewModel.comicBookEntity().currentReadingChaptersPosition();
//        smoothScrollToPosition(0,position);

    }

    /**
     * 预加载章节详情
     * @param preloadChapterId 预加载的章节ID
     */
    public void preInstallComicChaptersInfo(int preloadChapterId) {
        comicDataDAL.fetchPreInstallComicChaptersInfo(viewModel.comicBookEntity().id, preloadChapterId);
    }
    @StrategyAnnotation(event = {Url.PreInstallComicChaptersInfo, Url.tag_local_chapter}, threadMode = ThreadMode.ASYNC, threadAlias = "fetchChaptersInfoApi")
    public void fetchPreInstallComicChaptersInfoApiCallbackRefresh(final ChaptersResultsVO data, boolean isCache) {

        // 未获得数据，未获得章节详情信息，接口数据异常
        if(data == null || data.detailInfo == null) {
            return;
        }

        ComicBookEntity comicBookEntity = viewModel.comicBookEntity();
        // 没有加载漫画书
        if(comicBookEntity == null) {
            return;
        }

        // 填充漫画实体
        ChaptersInfo chaptersInfo = data.detailInfo.fillComic(comicBookEntity);

        // 更新底部收藏按钮状态，收藏状态在 fillComic 是被更新
        viewModel.refreshFavoriteBtnUI();

        // 更新加锁状态
        if(data.chapter_lock != null) {
            data.chapter_lock.refreshLockInfo();
            chaptersInfo.addLock();
        } else {
            chaptersInfo.unlock();
        }

        // 通过ID获取章节绑定的 ViewModel
        ComicReaderItemViewModel itemModel = viewModel.findComicReaderItemViewModel(data.detailInfo.id);
        if(itemModel != null) {
            // 刷新 ViewModel 通知UI修改。
            itemModel.refreshUI();
            //TODO：预加载需要另起线程下载图片。
//            itemModel.chaptersItemModel.loadAllPictureResource();
        }

        // 填充分享相关信息
        if(data.shareInfo != null) {
            viewModel.loadShareInfo(data.shareInfo.toShareInfo());
        }

        // 加载章节弹幕
        loadComicBulletScreen(comicBookEntity.id, chaptersInfo.id);

    }

    /**
     * 加载阅读漫画章节信息
     */
    public void installComicChaptersInfo(int loadChapterId) {
        comicDataDAL.fetchComicChaptersInfo(viewModel.comicBookEntity().id, loadChapterId);
    }
    @StrategyAnnotation(event = {Url.comicChaptersInfo, Url.tag_local_chapter}, threadMode = ThreadMode.ASYNC, threadAlias = "fetchChaptersInfoApi")
    public void fetchChaptersInfoApiCallbackRefresh(final ChaptersResultsVO data, boolean isCache) {

        // 未获得数据，未获得章节详情信息，接口数据异常
        if(data == null || data.detailInfo == null) {
            return;
        }

        ComicBookEntity comicBookEntity = viewModel.comicBookEntity();
        // 没有加载漫画书
        if(comicBookEntity == null) {
            return;
        }

        // 填充漫画实体
        ChaptersInfo chaptersInfo = data.detailInfo.fillComic(comicBookEntity);

        // 更新底部收藏按钮状态，收藏状态在 fillComic 是被更新
        viewModel.refreshFavoriteBtnUI();

        // 填充评论
        if(ArrayUtil.notEmpty(data.commentBest)) {
            data.fillComment(chaptersInfo);
        }

        // 填充加锁相关信息
        if(data.chapter_lock != null) {
            data.chapter_lock.refreshLockInfo();
            chaptersInfo.addLock();
        } else {
            chaptersInfo.unlock();
            refreshBalanceData();
        }

        // 自动解锁相关
        if(data.autoPay != null) {

            StringBuilder autoUnLockPrompt = new StringBuilder("本次消耗");
            if(!data.autoPay.unlock_coin.equals("0.0")) {
                autoUnLockPrompt.append(" ").append(data.autoPay.unlock_coin).append("金币");
            }
            if(!data.autoPay.unlock_bean.equals("0.0")) {
                autoUnLockPrompt.append(" ").append(data.autoPay.unlock_bean).append("金豆");
                chaptersInfo.directoryInfo().unlock3Days();
            }
            viewModel.showAutoUnlockToast(data.autoPay.unlock_msg, autoUnLockPrompt.toString());

            // todo:解锁之后为了刷新目录接口的http缓存，以解决第二次进入时缓存的解锁状态没有同步最新
//            new ComicReaderWarehouse(new Observer() {
//                @Override
//                public void update(String tag, Object data, boolean isCache) {
//                    if(!isCache)
//                        System.out.println("缓存更新成功！");
//                }
//            }).fetchComicDirectoryInfo(data.detailInfo.book_id);
        }

        // 阅读任务提示
        if(data.task != null && data.task.is_show == 1) {
            String msg = data.task.state == 1 ? "阅读2部漫画任务已完成" : "阅读2部漫画任务完成" + data.task.schedule + "/2";
            ToastHelper.showSnackBar(msg, Prompt.SUCCESS);
        }

        // 获取章节关联的ItemViewModel
        ComicReaderItemViewModel itemModel = viewModel.findComicReaderItemViewModel(chaptersInfo.id);
        if(itemModel != null) {
            // 点赞统计相关填充
            if(data.tj != null) {
                itemModel.loadChaptersGiveLikeData(data.tj.like_count, data.tj.like == 1);
            }

            delayTaskPool.doTaskByTag("INSTALL_COMIC");
            itemModel.refreshUI();

//        //TODO：预加载需要另起线程下载图片。
//        itemModel.chaptersItemModel.loadAllPictureResource();
        }

        // 填充分享相关信息
        if(data.shareInfo != null) {
            viewModel.loadShareInfo(data.shareInfo.toShareInfo());
        }

        // 不是缓存的情况下，提示vip免费阅读
        if(!isCache) {
            viewModel.showVipFreeToast();
        }

    }

    /**
     * 加载章节弹幕
     */
    private void loadComicBulletScreen(int comicId, int chapterId) {
        comicDataDAL.fetchComicBulletScreen(comicId, chapterId);
    }
    @StrategyAnnotation(event = Url.v5_comicBulletScreen_Fetch, threadAlias = "fetchBulletScreenApi")
    public void fetchBulletScreenApiCallbackRefresh(ChaptersBulletScreenVO data, boolean isCache) {

        if(data == null) {
            return;
        }

        ComicBookEntity comicBookEntity = viewModel.comicBookEntity();
        ChaptersInfo chaptersInfo = comicBookEntity.chaptersPreInstalled(data.chapterId);

        data.fillComicBulletScreen(chaptersInfo);

        viewModel.refreshComicReaderView();

    }


    //TODO: 需要实现DAL注解，可返回参数功能，应该有请求返回投递过去的数据
    private int readyUnlockChapterId = -1;
    /**
     * 解锁准备阅读章节通过购买
     * @param comicId   漫画ID
     * @param chapterId 章节ID
     * @param chapterPrice  章节价格
     * @param paymentType   支付方式
     * @param autoPay   自动购买标签
     */
    public void unlockChapterByBuy(int comicId, int chapterId, String chapterPrice, String paymentType, int autoPay) {
        readyUnlockChapterId = chapterId;
        comicDataDAL.unlockChapterByBuy(comicId, chapterId, chapterPrice, paymentType, autoPay);
    }
    @StrategyAnnotation(event = Url.ComicChapterUnlockByBuy)
    public void unlockChapterByBuyCallback(OkResponseVO dataVO, boolean isCache) {

        if(ObjectUtil.isNull(dataVO) || !dataVO.isOK()) {
            ToastHelper.showCenterDarkToast("", "解锁失败");
            return;
        }

        // 提示解锁结果
        ToastHelper.showCenterDarkToast("", dataVO.ok);

        // 获取解锁章节的ID
        final int chapterId = readyUnlockChapterId;
        final ComicBookEntity comicBookEntity = viewModel.comicBookEntity();

//        // 阅读解锁章节，理论上在阅读也需要解锁的章节，都一个是准备读的章节。
//        comicBookEntity.chaptersReading(chapterId).unlock();

        // 加载漫画章节信息,加载信息的返回结果会解锁当前章节，固不再此处在进行解锁了。
        installComicChaptersInfo(chapterId);

        // todo 保存历史记录
//        DBManager.getInstance().saveBook(new DBBook(comicBookEntity.id, comicBookEntity.bookName, chapterId));

        // 解锁章节刷新余额
        refreshBalanceData();

        // 第一次解锁必须点击解锁确定后才算解锁
        comicBookEntity.lockInfo().disableFirstUnlock();

        // 定位章节位置并移动到对应章节
        final int chapterPosition = comicBookEntity.getChaptersPositionByChapterId(chapterId);
        delayTaskPool.put("INSTALL_COMIC", () -> {
            viewModel.proxy().gotoChaptersPosition(chapterPosition);
        });



        // todo:解锁之后为了刷新目录接口的http缓存，以解决第二次进入时缓存的解锁状态没有同步最新
//        new ComicReaderWarehouse(new Observer() {
//            @Override
//            public void update(String tag, Object data, boolean isCache) {
//                if (!isCache)
//                    System.out.println("缓存更新成功！");
//            }
//        }).fetchComicDirectoryInfo(comicBookEntity.id);

    }

    /**
     * 解锁准备阅读的章节通过广告
     * @param comicId   漫画ID
     * @param chapterId 章节ID
     */
    public void unlockChapterByAd(int comicId, int chapterId) {
        readyUnlockChapterId = chapterId;
        comicDataDAL.unlockChapterByAdvert(comicId, chapterId);
    }
    @StrategyAnnotation(event = Url.ComicChapterUnlockByAd)
    public void unlockChapterByAdvertCallback(OkResponseVO dataVO, boolean isCache) {

        if(ObjectUtil.isNull(dataVO) || !dataVO.isOK()) {
            ToastHelper.showCenterDarkToast("", "解锁失败");
            return;
        }

        // 提示解锁结果
//        ToastHelper.showCenterDarkToast("", dataVO.ok);
        // TODO：服务器返回提示信息的话，可以合并2个解锁的处理方案
        ToastHelper.showCenterDarkToast("", "解锁成功，可免费阅读3天");

        // 获取解锁章节的ID
        final int chapterId = readyUnlockChapterId;
        final ComicBookEntity comicBookEntity = viewModel.comicBookEntity();

        // 加载漫画章节信息
        installComicChaptersInfo(chapterId);

        // todo 保存阅读的历史记录
//        DBManager.getInstance().saveBook(new DBBook(comicBookEntity.id, comicBookEntity.bookName, chapterId));

        // 解锁章节刷新余额
        refreshBalanceData();

        // 定位章节位置并移动到对应章节
        final int chapterPosition = comicBookEntity.getChaptersPositionByChapterId(chapterId);
        delayTaskPool.put("INSTALL_COMIC", () -> {
            viewModel.proxy().gotoChaptersPosition(chapterPosition);
        });

        // todo:解锁之后为了刷新目录接口的http缓存，以解决第二次进入时缓存的解锁状态没有同步最新
//        new ComicReaderWarehouse(new Observer() {
//            @Override
//            public void update(String tag, Object data, boolean isCache) {
//                if (!isCache)
//                    System.out.println("缓存更新成功！");
//            }
//        }).fetchComicDirectoryInfo(comicBookEntity.id);
    }

    /**
     * 提交弹幕
     * @param comicBookEntity 漫画书
     * @param bulletScreenInfo 弹幕
     */
    public void submitBullet(ComicBookEntity comicBookEntity, BulletScreenInfo bulletScreenInfo){
        int bookId      = comicBookEntity.id;
        int chapterId   = comicBookEntity.currentReadingChapters().id;
        String x        = bulletScreenInfo.xRatio().toString();
        String y        = bulletScreenInfo.yRatio().toString();
        String bulletContent = bulletScreenInfo.content;
        String fontColorTag  = bulletScreenInfo.fontColorTag;
        int fontSizeNumber   = bulletScreenInfo.fontSizeNumber;
        String imgUrl        = bulletScreenInfo.contentPictureToken();
        comicDataDAL.addComicBulletScreen(bookId, chapterId, x, y, bulletContent, fontColorTag, fontSizeNumber, imgUrl);
    }
    @StrategyAnnotation(event = Url.v5_comicBulletScreen_Add)
    public void addComicBulletScreenApiCallBack(TaskStateResponseVO dataVO, boolean isCache){
        if(dataVO.task_state == 1){
            ToastHelper.showSnackBar("发送弹幕任务完成", Prompt.SUCCESS);
        } else {
            ToastHelper.showSnackBar(dataVO.ok, Prompt.SUCCESS);
        }
    }

    /**
     * 首充福利检查接口，当余额不足且需要解锁漫画时调用检测是否具备新人首充福利资格。
     * @param isEnable true为开启首充福利，服务器开启倒计时，false则只检测是否已经开启
     */
    public void welfareCheck(boolean isEnable) {
        tradingDataDAL.welfareCheck(isEnable);
    }
    @StrategyAnnotation(event = Url.WelfareCheckInfo)
    public void welfareCheckCallback(NewcomerWelfareCheckVO data, boolean isCache) {
        if(data == null || data.welfare == null) {
            return;
        }

        if (0 == StringUtil.valueToInt(data.welfare.is_open, 0)) {
            viewModel.removeFirstBuyCoinViewToRoot();
            return;
        }
        if (data.welfare.ttl <= 0) {
            viewModel.removeFirstBuyCoinViewToRoot();
            return;
        }

        viewModel.insertFirstBuyCoinViewToRoot(data.welfare.ttl);
    }

    /**
     * 是否添加入书架，如果已收藏再次调用则取消收藏
     * @param comicBookEntity
     */
    public void whetherJoinMyBookshelf(ComicBookEntity comicBookEntity) {
        comicDataDAL.whetherJoinMyBookshelf(comicBookEntity.id, 0);
    }
    @StrategyAnnotation(event = Url.whetherJoinMyBookshelf)
    public void whetherJoinMyBookshelfApiCallbackRefresh(CollectTaskVO dataVO, boolean isCache) {
        if(ObjectUtil.isNull(dataVO) || dataVO.isFail()) {
            viewModel.refreshFavorite("收藏失败", "");
            return;
        }

        String resultMsg = dataVO.getResultMsg();
        String takeMsg = dataVO.getTaskMsg();
        viewModel.refreshFavorite(resultMsg, takeMsg);
    }

    /**
     * 给喜欢的章节点赞
     * @param comicId 漫画ID
     * @param chapterId 章节ID
     */
    public void giveLike(int comicId, int chapterId) {
        comicDataDAL.giveLike(comicId, chapterId);
    }
    @StrategyAnnotation(event = Url.ChapterGiveLike)
    public void giveLikeCallback(OkResponseVO data, boolean isCache) {
        ToastHelper.showSnackBar(data.ok, Prompt.SUCCESS);
    }

    /**
     * 账户余额API接口返回刷新回调*/
    private void refreshBalanceData() {
        userDataDAL.refreshBalanceData();
    }
    @StrategyAnnotation(event = Url.account_index)
    public void refreshBalanceDataApiCallbackRefresh(MyAccountVO data, boolean isCache){
        data.fillUserEntity();
    }

    /**
     * 给喜欢的评论点赞
     * @param bookId 评论所属漫画ID
     * @param commentId 评论ID
     */
    public void voteToGiveLikeComment(int bookId, int commentId) {
        commentDataDAL.voteToGiveLikeComment(bookId, commentId);
    }
    @StrategyAnnotation(event = Url.comment_like)
    public void voteToGiveLikeCommentApiCallBack(OkResponseVO dataVO, boolean isCache) {
        ToastHelper.showSnackBar(dataVO.ok, Prompt.SUCCESS);
    }

    /**
     * 上报漫画阅读人气数据
     * @param bookId
     * @param chapterId
     * @param scrollCount
     * @param screenHeight
     * @param comicHeight
     */
    public void reportComicPopular(int bookId, int chapterId, int scrollCount, int screenHeight, int comicHeight) {
        comicDataDAL.reportComicPopular(bookId, chapterId, scrollCount, screenHeight, comicHeight);
    }

    private class DelayTaskPool {
        private final HashMap<String, ArrayList<Action>> pool = new HashMap<>();

        public synchronized void put(String tag, Action action) {
            ArrayList<Action> list = pool.get(tag);
            if(list == null) {
                list = new ArrayList<>();
                pool.put(tag, list);
            }
            list.add(action);
        }

        public synchronized void doTaskByTag(String tag) {
            ArrayList<Action> list = pool.get(tag);
            for(Action action : list) {
                action.call();
            }
            list.clear();
        }
    }
}
